import { _decorator, Animation, CCFloat, CircleCollider2D, Collider2D, Color, Component, Contact2DType, IPhysics2DContact, math, Quat, RigidBody2D, Sprite, v2, v3, Vec2, Vec3 } from 'cc'
import { StateMachine } from '../fsm/StateMachine'
import { mathutil } from '../util/MathUtil'
import { collisionTag } from './CollisionTag'
import { StateDefine } from './StateDefine'
const { ccclass, property, requireComponent, disallowMultiple } = _decorator
// 标记一个类或方法需要特定的游戏组件。这种模式常见于游戏引擎中，用于定义实体（如游戏角色）必须具备哪些组件才能正常工作。
@ccclass('Actor')
@requireComponent(RigidBody2D)
@requireComponent(CircleCollider2D)
@disallowMultiple(true)
export class Actor extends Component {
    rigidBody: RigidBody2D | null = null
    collider: CircleCollider2D | null = null
    stateMgr: StateMachine<StateDefine> = new StateMachine()
    @property(Sprite)
    mainRenderer: Sprite
    @property(CCFloat)
    linearSpeed: number = 1
    @property(Animation)
    animation: Animation | null = null
    //
    hp: number = 100
    maxHp: number = 100
    @property(CCFloat)
    attack: number = 10
    input: Vec2 = v2()
    dead: boolean = false
    onLoad() {
        this.rigidBody = this.node.getComponent(RigidBody2D)
        this.collider = this.node.getComponent(CircleCollider2D)
        this.collider?.on(Contact2DType.BEGIN_CONTACT, this.onProjectileTriggerEnter, this)
    }
    start() {

    }

    update(deltaTime: number) {
        this.dead = this.hp <= 0
        this.stateMgr.update(deltaTime)
        this.mainRenderer.node.rotation = this.input.x >= 0 ? Quat.IDENTITY : mathutil.ROT_Y_180

    }
    onDestroy() {
        this.collider.off(Contact2DType.BEGIN_CONTACT, this.onProjectileTriggerEnter, this)
    }

    onProjectileTriggerEnter(self: Collider2D, cb: Collider2D, contact: IPhysics2DContact) {

        let isProjectileHitable = collisionTag.isProjectileHitable(cb.tag, self.tag)

        if (isProjectileHitable) {
            let hitNormal = v3()
            Vec3.subtract(hitNormal, self.node.worldPosition, cb.node.worldPosition)
            hitNormal.normalize()
            const v2HitNormal = v2(hitNormal.x, hitNormal.y)
            this.onHurt(this.attack, v2HitNormal)
        }
    }
    onHurt(damange: number, hurtDirection?: Vec2) {
        console.log('onHurt', damange, hurtDirection)
        this.hp = Math.floor(math.clamp(this.hp - damange, 0, this.maxHp))

        // 受力
        this.rigidBody.applyLinearImpulseToCenter(hurtDirection, true)
        this.mainRenderer.color = Color.RED
        this.scheduleOnce(() => {
            this.mainRenderer.color = Color.WHITE
        }, 0.2)
        if (this.hp <= 0) {
            this.stateMgr.transit(StateDefine.Die)
        }
    }

}

